﻿using System.Threading.Tasks;
using Xproject.Framework.Core;
using Xproject.Framework.Core.DataContext;
using Xproject.Framework.Core.Repositories;
using Model.WXshopBuiness;
using Model.WXshopBuiness.Enum;
using Repository.WXshopBuiness;
using Repository.Util;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using Model.Const;
using Model.Util;
using Model.WXshopBuiness.DTO;
using Model.Finance;

namespace Services.WXshopBuiness
{
    public class WXOrderServices:Service
    {
        IRepositoryAsync<WXProduct> m_WXProductRepository;
        IRepositoryAsync<WeiXinOrder> m_WeiXinOrderRepository;
        IRepositoryAsync<Identity> m_IdentityRepository;
        IRepositoryAsync<OrderChangeHistory> m_OrderChangeHistoryRepository;
        IRepositoryAsync<AccountBalance> m_AccountBalanceRepository;
        IRepositoryAsync<ShoppingCar> m_shoppingCarRepository;

        public WXOrderServices(IDataContextAsync dataContext) : base(dataContext)
        {
            m_WXProductRepository = m_UnitOfWork.RepositoryAsync<WXProduct>();
            m_IdentityRepository = m_UnitOfWork.RepositoryAsync<Identity>();
            m_WeiXinOrderRepository = m_UnitOfWork.RepositoryAsync<WeiXinOrder>();
            m_OrderChangeHistoryRepository = m_UnitOfWork.RepositoryAsync<OrderChangeHistory>();
            m_AccountBalanceRepository = m_UnitOfWork.RepositoryAsync<AccountBalance>();
            m_shoppingCarRepository = m_UnitOfWork.RepositoryAsync<ShoppingCar>();
        }

        public bool UpdatePruductSalesCountInfo(string productId)
        {
            WXProduct product = m_WXProductRepository.Get(productId);
            product.SaleCounts = product.SaleCounts + 1;
            product.EntityState = EntityState.Modified;
            product.UpdateTime = DateTime.Now;
            m_WXProductRepository.Update(product);
            return m_UnitOfWork.SaveChanges() == 1;
        }



        public bool UpdatePruductVisitCountInfo(string productId)
        {
            WXProduct product = m_WXProductRepository.Get(productId);
            product.VistiCounts = product.VistiCounts + 1;
            product.EntityState = EntityState.Modified;
            product.UpdateTime = DateTime.Now;
            m_WXProductRepository.Update(product);
            return m_UnitOfWork.SaveChanges() == 1;
        }


        public ShoppingCar GetShoppingCarById(string shopcarId)
        {
            if (string.IsNullOrEmpty(shopcarId))
            {
                return null;
            }
            return m_shoppingCarRepository.GetShopCarByID(shopcarId);
        }

        public ShoppingCar GetUserProductInCar(string userId, string productId, string specifationId,int state)
        {
            if (string.IsNullOrEmpty(userId) || string.IsNullOrEmpty(productId))
            {
                return null;
            }
            return m_shoppingCarRepository.GetUserShopCar(productId, userId, specifationId,state);
        }

        public List<ShoppingCar> GetUserShoppingCarList(string userId, int? pagesize, int? index, out int total)
        {
            List<ShoppingCar> allOrders = m_shoppingCarRepository.GetUserShoppingCarList(userId);
            total = allOrders.Count;
            if (index.HasValue && pagesize.HasValue)
            {
                allOrders = allOrders.Skip((index.Value - 1) * pagesize.Value).Take(pagesize.Value).ToList();
            }
            return allOrders;
        }

        public int GetUserShoppingCarCount(string userId)
        {
            return m_shoppingCarRepository.GetUserShoppingCarCount(userId);
        }

        public decimal GetUserShoppingCarMoney(string userId)
        {
            List<ShoppingCar> shopcar = m_shoppingCarRepository.GetUserShoppingCarList(userId);
            decimal total = 0.00M;
            foreach (ShoppingCar car in shopcar)
            {
                total += car.SinglePrice * car.ProductNum;
            }
            return total;
            
        }

        public bool UpdateUserShoppingCarNumsAndPrice(ShoppingCar shopcar,decimal saleprice,decimal marketprice, int nums)
        {
            shopcar.ProductNum = shopcar.ProductNum + nums;
            shopcar.SinglePrice = saleprice;
            shopcar.SingleOrigPrice = marketprice;
            shopcar.UpdateTime = DateTime.Now;
            shopcar.EntityState = EntityState.Modified;
            m_shoppingCarRepository.Update(shopcar);
            return m_UnitOfWork.SaveChanges() == 1;
        }

        public bool AddToShopingCar(ShoppingCar shopcar,WXProduct product, ProductSpecification specifation, string userId, int nums,string productUrl,string remarks)
        {
            shopcar.ShopCarId = Guid.NewGuid().ToString();
            shopcar.UpdateTime = shopcar.CreateTime = DateTime.Now;
            shopcar.EntityState = EntityState.Added;
            shopcar.ItemState = 0;
            shopcar.ProductDesc = product.ShortDesc;
            shopcar.ProductId = product.ProductID;
            shopcar.ProductImgUrl = product.Domain + product.ThumbnailUrl1;
            shopcar.ProductName = product.ProductName;
            shopcar.ProductNum = nums;
            if (specifation != null)
            {
                shopcar.ProductSpecificationId = specifation.ProductSpecificationId;
                shopcar.ProductSpecificationName = specifation.SpecificationName;
                shopcar.SinglePrice = specifation.SalesPrice;
                shopcar.SingleOrigPrice = specifation.OrignPrice;
            }
            else {
                shopcar.SingleOrigPrice = product.MarketPrice;
                shopcar.SinglePrice = product.SalePrice;
            }
            shopcar.ProductUrl = productUrl;
            shopcar.Remarks = remarks;            
            shopcar.UserId = userId;
            m_shoppingCarRepository.Insert(shopcar);
            return m_UnitOfWork.SaveChanges()==1;
        }

        public string CreateOrderCode(string pre,string projectId)
        {
            Identity iden = new Identity();
            iden.CreateTime = DateTime.Now;
            iden.EntityState = EntityState.Added;
            iden.ProjectID = projectId;
            iden.Guid = Guid.NewGuid().ToString();
            m_IdentityRepository.Insert(iden);
            m_UnitOfWork.SaveChanges();            
            Identity nid = m_IdentityRepository.Get(iden.Guid);
            string year = DateTime.Now.Year.ToString().Substring(2, 2);
            string Monty = DateTime.Now.Month.ToString();
            string day = DateTime.Now.Day.ToString();            
             
            return pre+ year+Monty+day + nid.ID.ToString();
        }

        public bool AddToOrder(ShoppingCar shoppingCar,string orderName, string userId,decimal ordermoney, int productNums,string productId,string remark
            ,decimal useScore,decimal useCash,decimal useBalance,decimal useCoupon,int platform,out string orderid
            ) {
            WeiXinOrder order = new WeiXinOrder();
            order.ShopCarId = shoppingCar.ShopCarId;
            orderid = order.OrderID = Guid.NewGuid().ToString().Replace("-","");
            order.UserID = userId;
            order.OrderCode = CreateOrderCode("O", productId);
            order.OrderMoney = ordermoney;
            order.CreateTime = DateTime.Now;
            order.OrderSource =(int) Enum_OrderSource.WXSHOP;
            order.PayType = (int)Enum_PayType.WEIXIN;
            order.OrderState = (int)Enum_OrderState.WAITINGPAY;
            order.Remark = remark;
            order.UseScore = useScore;
            order.UseCash = useCash;
            order.UseBalance = useBalance;
            order.UseCoupon = useCoupon;
            order.Platform = platform;
            order.ProductId = productId;
            order.OrderName = orderName;
            order.ProductNum = productNums;
            order.ThatTimeSalePrice = shoppingCar.SinglePrice;
            order.EntityState = EntityState.Added;
            m_WeiXinOrderRepository.Insert(order);
            shoppingCar.EntityState = EntityState.Modified;
            shoppingCar.UpdateTime = DateTime.Now;
            shoppingCar.ItemState = 1;//这个购物车已做支付动作，将不会出现在购物车
            m_shoppingCarRepository.Update(shoppingCar);
            return (m_UnitOfWork.SaveChanges() == 2);
            
        }

        public bool AddToShoppingCartOld(  string orderName, string userId, decimal ordermoney,   string productId, string remark
         , decimal useScore, decimal useCash, decimal useBalance, decimal useCoupon, int platform
         )
        {
            WeiXinOrder order = new WeiXinOrder();
              order.OrderID = Guid.NewGuid().ToString().Replace("-", "");
            order.UserID = userId;
            order.OrderCode = CreateOrderCode("O", productId);
            order.OrderMoney = ordermoney;
            order.CreateTime = DateTime.Now;
            order.OrderSource = (int)Enum_OrderSource.WXSHOP;
            order.PayType = (int)Enum_PayType.WEIXIN;
            order.OrderState = (int)Enum_OrderState.SHOPCAR;
            order.Remark = remark;
            order.UseScore = useScore;
            order.UseCash = useCash;
            order.UseBalance = useBalance;
            order.UseCoupon = useCoupon;
            order.Platform = platform;
            order.ProductId = productId;
            order.OrderName = orderName;
            
            order.EntityState = EntityState.Added;
            m_WeiXinOrderRepository.Insert(order);

            return (m_UnitOfWork.SaveChanges() == 1);

        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="orderId"></param>
        /// <returns></returns>
        public WeiXinOrder GetById(string orderId)
        {
            return m_WeiXinOrderRepository.Get(orderId);
         }
        /// <summary>
        /// 得到用户订单
        /// </summary>
        /// <param name="userId"></param>
        /// <param name="state"></param>
        /// <returns></returns>
        public List<WeiXinOrder> GetUserOrderList(string userId, int state)
        {
            return m_WeiXinOrderRepository.GetUserOrderList(userId, state);
        }

        public List<OrderInfoModel> GetUserOrderDetailList(string userId, int state)
        {
            return m_WeiXinOrderRepository.GetUserAllOrderDetailList(userId, state);
        }

        public List<OrderInfoModel> AdminGetUserOrderDetailList(string site,int offset, int limit, string orderCode, string userCode, string mobile, int? orderState, int? orderSource, int? payType, DateTime? startTime, DateTime? endTime, string order, string ordername,out int total)
        {
            total = 0;
            List<OrderInfoModel> list = m_WeiXinOrderRepository.AdminGetUserOrderDetailList(offset,limit,orderCode,userCode,mobile,orderState,orderSource,payType,startTime,endTime,order,ordername);
            if (list != null && list.Count > 0)
            {
                total = list.FirstOrDefault().Total;
            }
            return list;
        }

        #region 前端使用
        /// <summary>
        /// 暂时废弃
        /// </summary>
        /// <param name="userId"></param>
        /// <param name="pagesize"></param>
        /// <param name="index"></param>
        /// <param name="total"></param>
        /// <returns></returns>
        //public List<WeiXinOrder> GetUserAllOrderList(string userId, int? pagesize, int? index, out int total)
        //{
        //    List<WeiXinOrder> allOrders = m_WeiXinOrderRepository.GetUserAllOrderList(userId);
        //    total = allOrders.Count;
        //    if (index.HasValue && pagesize.HasValue)
        //    {
        //        allOrders = allOrders.Skip((index.Value - 1) * pagesize.Value).Take(pagesize.Value).ToList();
        //    }
        //    return allOrders;
        //}
        public List<OrderInfoModel> GetUserAllOrderDetailList(string userId, int? pagesize, int? index, out int total)
        {
            List<OrderInfoModel> allOrders = m_WeiXinOrderRepository.GetUserAllOrderDetailList(userId);
            total = allOrders.Count;
            if (index.HasValue && pagesize.HasValue)
            {
                allOrders = allOrders.Skip((index.Value - 1) * pagesize.Value).Take(pagesize.Value).ToList();
            }
            return allOrders;
        }

        public List<OrderInfoModel> GetUserOrderDetailList(string userId, int state, int? pagesize, int? index, out int total)
        {
            List<OrderInfoModel> allOrders = GetUserOrderDetailList(userId, state);
            total = allOrders.Count;
            if (index.HasValue && pagesize.HasValue)
            {
                allOrders = allOrders.Skip((index.Value - 1) * pagesize.Value).Take(pagesize.Value).ToList();
            }
            return allOrders;
        }
        /// <summary>
        ///  
        /// </summary>
        /// <param name="userId"></param>
        /// <param name="state"></param>
        /// <param name="pagesize"></param>
        /// <param name="index"></param>
        /// <param name="total"></param>
        /// <returns></returns>
        public List<WeiXinOrder> GetUserOrderList(string userId, int state, int? pagesize, int? index, out int total)
        {
            List<WeiXinOrder> allOrders = GetUserOrderList(userId, state);
            total = allOrders.Count;
            if (index.HasValue && pagesize.HasValue)
            {
                allOrders = allOrders.Skip((index.Value - 1) * pagesize.Value).Take(pagesize.Value).ToList();
            }
            return allOrders;
        }

        public OrderInfoModel GetOrderById(string orderId)
        {
            return m_WeiXinOrderRepository.GetOrderInfoByOrderId(orderId);
        }

        public WeiXinOrder GetDBOrderById(string orderId)
        {
            return m_WeiXinOrderRepository.Get(orderId);
        }

        public bool DelShopCar(ShoppingCar shoppingCar)
        {
            shoppingCar.EntityState = EntityState.Deleted;           
            m_shoppingCarRepository.Delete(shoppingCar);              
            return m_UnitOfWork.SaveChanges() == 1;
        }
        public bool DelOrder(WeiXinOrder order, OrderChangeHistory history)
        {
            order.EntityState = EntityState.Deleted;
            order.UpdateTime = DateTime.Now;
            history.EntityState = EntityState.Added;
            history.CreateTime = DateTime.Now;
            history.ID = Guid.NewGuid().ToString();
            m_OrderChangeHistoryRepository.Insert(history);
            m_WeiXinOrderRepository.Update(order);
            return m_UnitOfWork.SaveChanges() == 2;
        } 

        public bool UpdateDBOrderInfo(WeiXinOrder order,OrderChangeHistory history)
        {
            order.EntityState = EntityState.Modified;
            order.UpdateTime = DateTime.Now;
            history.EntityState = EntityState.Added;
            history.CreateTime = DateTime.Now;
            history.ID = Guid.NewGuid().ToString();
            m_OrderChangeHistoryRepository.Insert(history);                          
            m_WeiXinOrderRepository.Update(order);
            return m_UnitOfWork.SaveChanges() == 2;
        }
        /// <summary>
        /// 订单支付成功
        /// </summary>
        /// <param name="order"></param>
        /// <returns></returns>
        public bool WeiXinPaySuccess(WeiXinOrder order, OrderChangeHistory history)
        {
            order.EntityState = EntityState.Modified;
            order.UpdateTime = DateTime.Now;
            history.EntityState = EntityState.Added;
            history.CreateTime = DateTime.Now;
            history.ID = Guid.NewGuid().ToString();
            m_WeiXinOrderRepository.Update(order);
            m_OrderChangeHistoryRepository.Insert(history);
            //加上流水表信息
            AccountBalance balance = new AccountBalance();
            balance.BalanceMoney = 0-order.OrderMoney;//消费记做负数
            balance.BuinessCode = (int)EnumAccountBalance_BuinessCode.支付;
            balance.CreateTime = DateTime.Now;
            balance.EntityState = EntityState.Added;
            balance.OrgaCode = (int)EnumAccountBalance_OrgaCode.微信支付;
            balance.RelationId = order.OrderID;
            balance.UserId = order.UserID;
            balance.AccountBalanceCode = CreateOrderCode("ZF", order.OrderID);
            m_AccountBalanceRepository.Insert(balance);
            return m_UnitOfWork.SaveChanges() == 3;
        }
        #endregion


    }
}
